package com.sky.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.sky.constant.MessageConstant;
import com.sky.context.BaseContext;
import com.sky.dto.OrdersDTO;
import com.sky.dto.OrdersPaymentDTO;
import com.sky.dto.OrdersSubmitDTO;
import com.sky.entity.*;
import com.sky.exception.AddressBookBusinessException;
import com.sky.exception.OrderBusinessException;
import com.sky.exception.ShoppingCartBusinessException;
import com.sky.mapper.*;
import com.sky.service.OrdersService;
import com.sky.utils.WeChatPayUtil;
import com.sky.vo.OrderPaymentVO;
import com.sky.vo.OrderSubmitVO;
import com.sky.websocket.WebSocketServer;
import com.sun.org.apache.bcel.internal.generic.NEW;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;

@Service
public class OrdersServiceImpl implements OrdersService {
    @Autowired
    AddressBookMapper addressBookMapper;

    @Autowired
    ShoppingCartMapper shoppingCartMapper;

    @Autowired
    UserMapper userMapper;

    @Autowired
    OrdersMapper ordersMapper;

    @Autowired
    OrderDetailMapper orderDetailMapper;

    @Autowired
    WeChatPayUtil weChatPayUtil;

    @Autowired
    private WebSocketServer webSocketServer;

    /**
     * 提交订单
     * @param ordersSubmitDTO
     * @return
     */
    @Transactional
    @Override
    public OrderSubmitVO submitOrder(OrdersSubmitDTO ordersSubmitDTO) {
        //意外一:没有地址
        //根据地址id查询地址簿
        AddressBook addressBook = addressBookMapper.findById(ordersSubmitDTO.getAddressBookId());
        if(addressBook == null){
            throw new AddressBookBusinessException(MessageConstant.ADDRESS_BOOK_IS_NULL);
        }
        //意外二:购物车没数据
        Long userId = BaseContext.getCurrentId();
        //根据用户id查询购物车
        List<ShoppingCart> shoppingCartList = shoppingCartMapper.findByUserId(userId);
        if(shoppingCartList == null || shoppingCartList.size()==0){
            throw new ShoppingCartBusinessException(MessageConstant.SHOPPING_CART_IS_NULL);
        }
        //===================1.添加orders表===================
        Orders orders = new Orders();
        //把数据拷贝到orders中
        BeanUtils.copyProperties(ordersSubmitDTO,orders);
        //设置9个
        //订单号
        orders.setNumber(String.valueOf(System.currentTimeMillis()));
        //状态 => 未支付 => 1
        orders.setStatus(Orders.PENDING_PAYMENT);
        //用户id
        orders.setUserId(userId);
        //下单时间
        orders.setOrderTime(LocalDateTime.now());
        //支付状态 => 0未支付
        orders.setPayStatus(Orders.UN_PAID);
        //用户名 => user表中的用户名
        User user = userMapper.findById(userId);
        orders.setUserName(user.getName());
        //收货人
        orders.setConsignee(addressBook.getConsignee());
        //手机号
        orders.setPhone(addressBook.getPhone());
        //地址 => 需要手动拼接 省+市+区+详细地址
        orders.setAddress((addressBook.getProvinceName() == null ? "" : addressBook.getProvinceName())
                + (addressBook.getCityName() == null ? "" : addressBook.getCityName())
                + (addressBook.getDistrictName() == null ? "" : addressBook.getDistrictName())
                + (addressBook.getDetail() == null ? "" : addressBook.getDetail()));
        //保存订单
        ordersMapper.save(orders);
        //=========================================================
        //===================2.添加order_detail表===================
        shoppingCartList.forEach(
            shoppingCart -> {
                //构造订单详情
                OrderDetail orderDetail = new OrderDetail();
                BeanUtils.copyProperties(shoppingCart,orderDetail);
                orderDetail.setId(null);
                //设置order的id
                orderDetail.setOrderId(orders.getId());
                //把每一个订单详情保存到数据库中
                orderDetailMapper.saveOrderDetail(orderDetail);
            }
        );
        //===================3.清空购物车 shopping_cart===================
        shoppingCartMapper.clean(userId);

        //4.构造vo
        return   OrderSubmitVO.builder()
                .id(orders.getId())
                .orderNumber(orders.getNumber())
                .orderAmount(orders.getAmount())
                .orderTime(orders.getOrderTime())
                .build();
    }

    /**
     * 支付成功更改订单的状态
     * @param orderNum
     */
    @Override
    public void paySuccess(String orderNum) {
        //1.查询订单 => 订单号
        //?思考?如果在这里我们想要获取用户的id我们可以怎么操作?
        //站在后台和微信的角度去考虑
        Orders orderDB = ordersMapper.findOrderByNum(orderNum);
        //2.修改订单的状态
        ordersMapper.update(
                Orders.builder()
                        .id(orderDB.getId())
                        .status(Orders.TO_BE_CONFIRMED)
                        .payStatus(Orders.PAID)
                        .checkoutTime(LocalDateTime.now())
                        .build()
        );
        //当我们用户支付后,微信会将支付结果告诉苍穹外卖
        //告诉员工管理端,有哥们下单了,得抓紧接单
        HashMap<String, Object> params = new HashMap<>();
        params.put("type",1);
        params.put("orderId",orderDB.getId()+"");
        params.put("content","订单号: "+orderDB.getNumber());
        String jsonResult = JSONObject.toJSONString(params);
        webSocketServer.sendToAllClient(jsonResult);
    }

    @Override
    public OrderPaymentVO payment(OrdersPaymentDTO ordersPaymentDTO) {

        // 当前登录用户id
        Long userId = BaseContext.getCurrentId();
        User user = userMapper.findById(userId);

        //调用微信支付接口，生成预支付交易单
        JSONObject jsonObject = null;
        try {
            jsonObject = weChatPayUtil.pay(
                    ordersPaymentDTO.getOrderNumber(), //商户订单号
                    //实际支付金额
                    new BigDecimal(0.01), //支付金额，单位 元
                    //商品描述
                    "描述", //商品描述
                    user.getOpenid() //微信用户的openid
            );
        } catch (Exception e) {
            throw new RuntimeException("支付失败");
        }

        if (jsonObject.getString("code") != null && jsonObject.getString("code").equals("ORDERPAID")) {
            throw new OrderBusinessException("该订单已支付");
        }

        OrderPaymentVO vo = jsonObject.toJavaObject(OrderPaymentVO.class);
        vo.setPackageStr(jsonObject.getString("package"));
        return vo;

    }
}
